<template>
  <div class="app-container">
    <h1>Anki 卡片生成器</h1>

    <!-- 添加配置按钮 -->
    <div class="header-actions">
      <button @click="showConfig = true" class="config-button">AnkiConnect 配置</button>
    </div>

    <!-- 配置面板作为弹出框 -->
    <ConfigPanel
      :config="ankiConfig"
      :visible="showConfig"
      :available-decks="availableDecks"
      :is-loading-decks="isLoadingDecks"
      :available-models="availableModels"
      :is-loading-models="isLoadingModels"
      :model-fields="modelFields"
      :is-loading-model-fields="isLoadingModelFields"
      @save-config="saveConfig"
      @refresh-decks="refreshDecks"
      @refresh-models="refreshModels"
      @model-name-changed="onModelNameChange"
      @close="showConfig = false"
    />
    <!-- 文本输入区域 -->
    <div class="input-section">
      <h2>输入文本</h2>
      <textarea v-model="rawText" placeholder="请输入需要解析的文本，格式为：问题 答案\n每行一个卡片" rows="10"></textarea>
      <div class="parse-options">
        <button @click="parseText" class="primary-button">解析文本</button>
        <p class="format-hint">格式提示：每行一个问答卡片，第一个空格前是问题，空格后是答案</p>
      </div>
    </div>

    <!-- 字段映射区域 -->
    <div v-if="cards.length > 0 && modelFields.length > 0" class="field-mapping-section">
      <h3>字段映射设置</h3>
      <div class="field-mapping-controls">
        <div class="field-mapping-item">
          <label for="questionField">问题对应字段：</label>
          <select
            id="questionField"
            v-model="fieldMapping.questionField"
            class="field-select"
          >
            <option v-for="field in modelFields" :key="field" :value="field">{{ field }}</option>
          </select>
        </div>
        <div class="field-mapping-item">
          <label for="answerField">答案对应字段：</label>
          <select
            id="answerField"
            v-model="fieldMapping.answerField"
            class="field-select"
          >
            <option v-for="field in modelFields" :key="field" :value="field">{{ field }}</option>
          </select>
        </div>
        <button @click="batchApplyFieldMapping" class="apply-mapping-button primary-button">批量应用映射</button>
      </div>
      <p class="mapping-hint" v-if="!fieldMapping.questionField || !fieldMapping.answerField">
        请选择问题和答案对应的模型字段，以便正确导出到Anki。
      </p>
      <p class="mapping-info" v-else>
        当前映射：问题内容将导出到 "{{ fieldMapping.questionField }}" 字段，答案内容将导出到 "{{ fieldMapping.answerField }}" 字段
      </p>
    </div>


    <!-- 卡片管理区域 -->
    <div class="cards-section">
      <h2>解析结果 (共 {{ cards.length }} 张卡片)</h2>

      <div class="cards-controls">
        <button @click="exportAllToAnki" class="primary-button">批量导出到Anki</button>
        <button @click="generateCsv" class="secondary-button">生成CSV文件</button>
        <button @click="clearAll" class="danger-button">清空所有</button>
      </div>

      <div class="cards-list">
        <div v-for="(card, index) in cards" :key="index" class="card-item">
          <div class="card-header">
            <span class="card-index">#{{ index + 1 }}</span>
            <div class="card-actions">
              <button @click="editCard(index)" class="edit-button">编辑</button>
              <button @click="deleteCard(index)" class="delete-button">删除</button>
              <button @click="exportSingleCard(index)" class="export-button">导出</button>
            </div>
          </div>

          <div v-if="editingIndex !== index" class="card-content">
            <div class="card-question">
              <strong>问题 ({{ fieldMapping.questionField }}):</strong>
              <p>{{ card.question }}</p>
            </div>
            <div class="card-answer">
              <strong>答案 ({{ fieldMapping.answerField }}):</strong>
              <p>{{ card.answer }}</p>
            </div>
          </div>

          <div v-else class="card-edit-form">
            <div class="form-group">
              <label>问题 ({{ fieldMapping.questionField }}):</label>
              <textarea v-model="editForm.question" rows="3"></textarea>
            </div>
            <div class="form-group">
              <label>答案 ({{ fieldMapping.answerField }}):</label>
              <textarea v-model="editForm.answer" rows="3"></textarea>
            </div>
            <div class="edit-actions">
              <button @click="saveCard" class="save-button">保存</button>
              <button @click="cancelEdit" class="cancel-button">取消</button>
            </div>
          </div>
        </div>
      </div>
    </div>

    <!-- 状态提示 -->
    <div v-if="statusMessage" :class="['status-message', statusType]">
      {{ statusMessage }}
    </div>
  </div>
</template>


<script>
import ConfigPanel from './ConfigPanel.vue';

export default {
  name: 'App',
  components: {
    ConfigPanel
  },
  data() {
    return {
      rawText: '',
      cards: [],
      editingIndex: -1,
      editForm: {
        question: '',
        answer: ''
      },
      statusMessage: '',
      statusType: 'info', // info, success, error
      // 新增：控制配置面板显示状态
      showConfig: false,
      // AnkiConnect 配置
      ankiConfig: {
        server: 'ankiAnalyze.yhl.zone',
        port: 80,
        deckName: '',
        modelName: '',
        apiKey: ''
      },
      // 新增：存储可用的Deck列表
      availableDecks: [],
      isLoadingDecks: false,
      availableModels: [],  // 添加Model列表
      isLoadingModels: false,  // 添加Model加载状态
      // 新增：存储当前选中模型的字段信息
      modelFields: [],
      isLoadingModelFields: false,
      // 新增：字段映射配置
      fieldMapping: {
        questionField: '正面',
        answerField: '背面'
      }
    }
  },
  mounted() {
    // 从localStorage加载配置
    this.loadConfig();
    // 尝试自动获取Deck和Model列表
    if (this.ankiConfig.server && this.ankiConfig.port) {
      this.testConnection();
      // 初始化时获取模型字段
      if (this.ankiConfig.modelName) {
        this.fetchModelFields(this.ankiConfig.modelName);
      }
    }
  },
  methods: {
    // 加载配置
    loadConfig() {
      const savedConfig = localStorage.getItem('ankiConnectConfig');
      if (savedConfig) {
        try {
          this.ankiConfig = { ...this.ankiConfig, ...JSON.parse(savedConfig) };
          this.showStatus('配置已加载', 'info');
        } catch (error) {
          console.error('加载配置失败:', error);
        }
      }
    },

    // 保存配置
    saveConfig(configData) {
      this.ankiConfig = { ...this.ankiConfig, ...configData };
      console.log('this.配置 ', configData)
      localStorage.setItem('ankiConnectConfig', JSON.stringify(configData));
      this.showStatus('配置已保存', 'success');
    },

    // 测试连接
    testConnection() {
      const url = `http://${this.ankiConfig.server}:${this.ankiConfig.port}`;
      const requestBody = {
        action: 'version',
        version: 6
      };

      if (this.ankiConfig.apiKey) {
        requestBody.key = this.ankiConfig.apiKey;
      }

      fetch(url, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json'
        },
        body: JSON.stringify(requestBody)
      })
        .then(response => {
          if (!response.ok) {
            throw new Error(`HTTP错误! 状态码: ${response.status}`);
          }
          return response.json();
        })
        .then(data => {
          if (data.error) {
            throw new Error(`Anki Connect错误: ${data.error}`);
          }
          this.showStatus(`连接成功! Anki Connect版本: ${data.result}`, 'success');
          // 连接成功后，同时获取可用的Deck列表和Model列表
          this.fetchAvailableDecks();
          this.fetchAvailableModels();
        })
        .catch(error => {
          this.showStatus(`连接失败: ${error.message}`, 'error');
          console.error('连接测试失败:', error);
        });
    },

    // 新增：获取Anki中可用的Deck列表
    fetchAvailableDecks() {
      this.isLoadingDecks = true;
      const url = `http://${this.ankiConfig.server}:${this.ankiConfig.port}`;
      const requestBody = {
        action: 'deckNames',
        version: 6
      };

      if (this.ankiConfig.apiKey) {
        requestBody.key = this.ankiConfig.apiKey;
      }

      fetch(url, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json'
        },
        body: JSON.stringify(requestBody)
      })
        .then(response => {
          if (!response.ok) {
            throw new Error(`HTTP错误! 状态码: ${response.status}`);
          }
          return response.json();
        })
        .then(data => {
          if (data.error) {
            throw new Error(`获取Deck列表失败: ${data.error}`);
          }

          // 更新可用Deck列表
          this.availableDecks = data.result;

          // 如果当前选择的Deck不存在于列表中，选择第一个
          if (this.availableDecks.length > 0 && !this.availableDecks.includes(this.ankiConfig.deckName)) {
            this.ankiConfig.deckName = this.availableDecks[0];
          }

          this.showStatus(`成功获取 ${this.availableDecks.length} 个可用Deck`, 'info');
        })
        .catch(error => {
          this.showStatus(`获取Deck列表失败: ${error.message}`, 'error');
          console.error('获取Deck列表错误:', error);
        })
        .finally(() => {
          this.isLoadingDecks = false;
        });
    },

    // 新增：手动刷新Deck列表
    refreshDecks() {
      this.fetchAvailableDecks();
    },

    // 新增：获取Anki中可用的Model列表
    fetchAvailableModels() {
      this.isLoadingModels = true;
      const url = `http://${this.ankiConfig.server}:${this.ankiConfig.port}`;
      const requestBody = {
        action: 'modelNames',
        version: 6
      };

      if (this.ankiConfig.apiKey) {
        requestBody.key = this.ankiConfig.apiKey;
      }

      fetch(url, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json'
        },
        body: JSON.stringify(requestBody)
      })
        .then(response => {
          if (!response.ok) {
            throw new Error(`HTTP错误! 状态码: ${response.status}`);
          }
          return response.json();
        })
        .then(data => {
          if (data.error) {
            throw new Error(`获取Model列表失败: ${data.error}`);
          }

          // 更新可用Model列表
          this.availableModels = data.result;

          // 如果当前选择的Model不存在于列表中，选择第一个或保持默认的Basic
          if (this.availableModels.length > 0) {
            if (!this.ankiConfig.modelName || !this.availableModels.includes(this.ankiConfig.modelName)) {
              // 优先选择Basic模型，如果存在的话
              if (this.availableModels.includes('Basic')) {
                this.ankiConfig.modelName = 'Basic';
              } else {
                this.ankiConfig.modelName = this.availableModels[0];
              }
            }
          }

          this.showStatus(`成功获取 ${this.availableModels.length} 个可用Model`, 'info');
        })
        .catch(error => {
          this.showStatus(`获取Model列表失败: ${error.message}`, 'error');
          console.error('获取Model列表错误:', error);
        })
        .finally(() => {
          this.isLoadingModels = false;
        });
    },

    // 新增：手动刷新Model列表
    refreshModels() {
      this.fetchAvailableModels().then(() => {
        if (this.ankiConfig.modelName) {
          this.fetchModelFields(this.ankiConfig.modelName);
        }
      });
    },

    // 获取指定模型的字段信息
    fetchModelFields(modelName) {
      if (!modelName) return;

      this.isLoadingModelFields = true;
      const url = `http://${this.ankiConfig.server}:${this.ankiConfig.port}`;
      const requestBody = {
        action: 'modelFieldNames',
        version: 6,
        params: {
          modelName: modelName
        }
      };

      if (this.ankiConfig.apiKey) {
        requestBody.key = this.ankiConfig.apiKey;
      }

      fetch(url, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json'
        },
        body: JSON.stringify(requestBody)
      })
        .then(response => {
          if (!response.ok) {
            throw new Error(`HTTP错误! 状态码: ${response.status}`);
          }
          return response.json();
        })
        .then(data => {
          if (data.error) {
            throw new Error(`获取模型字段失败: ${data.error}`);
          }

          this.modelFields = data.result;
          console.log(`成功获取 ${modelName} 模型的字段:`, this.modelFields);

          // 新增：当模型字段加载完成后，自动设置默认映射
          if (this.modelFields.length > 0) {
            // 如果当前没有设置问题字段，或者设置的字段不存在于模型字段中
            if (!this.fieldMapping.questionField || !this.modelFields.includes(this.fieldMapping.questionField)) {
              // 优先选择'正面'或'Front'，如果存在的话
              if (this.modelFields.includes('正面')) {
                this.fieldMapping.questionField = '正面';
              } else if (this.modelFields.includes('Front')) {
                this.fieldMapping.questionField = 'Front';
              } else {
                // 否则选择第一个字段
                this.fieldMapping.questionField = this.modelFields[0];
              }
            }

            // 如果当前没有设置答案字段，或者设置的字段不存在于模型字段中
            if (!this.fieldMapping.answerField || !this.modelFields.includes(this.fieldMapping.answerField)) {
              // 优先选择'背面'或'Back'，如果存在的话
              if (this.modelFields.includes('背面')) {
                this.fieldMapping.answerField = '背面';
              } else if (this.modelFields.includes('Back')) {
                this.fieldMapping.answerField = 'Back';
              } else {
                // 否则选择第二个字段，如果有的话，否则选择第一个字段
                this.fieldMapping.answerField = this.modelFields.length > 1 ? this.modelFields[1] : this.modelFields[0];
              }
            }
          }
        })
        .catch(error => {
          console.error('获取模型字段错误:', error);
          this.modelFields = [];
        })
        .finally(() => {
          this.isLoadingModelFields = false;
        });
    },

    // 监听modelName变化，自动获取字段
    onModelNameChange(newModelName) {
      this.ankiConfig.modelName = newModelName;
      this.fetchModelFields(newModelName);
    },

    // 解析文本为卡片 - 不跳过任何非空行
    parseText() {
      if (!this.rawText.trim()) {
        this.showStatus('请输入要解析的文本', 'error');
        return;
      }

      try {
        let newCards = [];
        const lines = this.rawText.split('\n');

        for (const line of lines) {
          const trimmedLine = line.trim();
          if (trimmedLine) { // 只跳过空行
            // 使用正则表达式匹配第一个空格或多个连续空格
            const firstSpaceMatch = trimmedLine.match(/\s+/);

            let question, answer;

            if (firstSpaceMatch) { // 有空格分隔
              const firstSpaceIndex = firstSpaceMatch.index;
              question = trimmedLine.substring(0, firstSpaceIndex).trim();
              answer = trimmedLine.substring(firstSpaceIndex + firstSpaceMatch[0].length).trim();
            } else { // 没有空格分隔，整行作为问题，答案留空
              question = trimmedLine;
              answer = '';
            }

            // 不跳过任何行，即使没有答案
            newCards.push({
              question: question,
              answer: answer
            });
          }
        }

        this.cards = newCards;
        this.showStatus(`成功解析出 ${newCards.length} 张卡片`, 'success');
      } catch (error) {
        this.showStatus('解析失败：' + error.message, 'error');
        console.error('解析错误:', error);
      }
    },

    // 其他方法保持不变

    // 新增：批量应用字段映射
    batchApplyFieldMapping() {
      if (!this.fieldMapping.questionField || !this.fieldMapping.answerField) {
        this.showStatus('请先选择问题字段和答案字段', 'error');
        return;
      }

      // 验证映射的字段是否存在于当前模型字段中
      if (this.modelFields.length > 0) {
        if (!this.modelFields.includes(this.fieldMapping.questionField)) {
          this.showStatus(`问题字段映射无效: ${this.fieldMapping.questionField} 不存在于当前模型的字段中`, 'error');
          return;
        }
        if (!this.modelFields.includes(this.fieldMapping.answerField)) {
          this.showStatus(`答案字段映射无效: ${this.fieldMapping.answerField} 不存在于当前模型的字段中`, 'error');
          return;
        }
      }

      this.showStatus(`字段映射已批量应用：问题 -> ${this.fieldMapping.questionField}，答案 -> ${this.fieldMapping.answerField}`, 'success');

      // 记录日志，方便调试
      console.log('字段映射已应用:', this.fieldMapping);
    },
    editCard(index) {
      const card = this.cards[index];
      this.editForm = {
        question: card.question,
        answer: card.answer
      };
      this.editingIndex = index;
    },

    saveCard() {
      if (this.editingIndex >= 0 && this.editingIndex < this.cards.length) {
        this.cards[this.editingIndex] = {
          question: this.editForm.question.trim(),
          answer: this.editForm.answer.trim()
        };
        this.showStatus('卡片已更新', 'success');
        this.cancelEdit();
      }
    },

    cancelEdit() {
      this.editingIndex = -1;
      this.editForm = { question: '', answer: '' };
    },

    deleteCard(index) {
      this.cards.splice(index, 1);
      this.showStatus('卡片已删除', 'info');
    },

    clearAll() {
      if (confirm('确定要清空所有卡片吗？')) {
        this.cards = [];
        this.showStatus('所有卡片已清空', 'info');
      }
    },

    exportToAnki(cards) {
      return new Promise((resolve, reject) => {
        try {
          // 验证参数
          if (!cards || !Array.isArray(cards)) {
            throw new Error('参数必须是卡片数组');
          }

          // 验证配置
          if (!this.ankiConfig.deckName || !this.ankiConfig.modelName) {
            throw new Error('请先配置Deck名称和Model名称');
          }

          // 验证字段映射
          if (!this.fieldMapping.questionField || !this.fieldMapping.answerField) {
            throw new Error('请先配置字段映射');
          }

          // 验证字段映射是否有效
          if (!this.modelFields.includes(this.fieldMapping.questionField)) {
            throw new Error(`问题字段映射无效: ${this.fieldMapping.questionField} 不存在于当前模型的字段中`);
          }
          if (!this.modelFields.includes(this.fieldMapping.answerField)) {
            throw new Error(`答案字段映射无效: ${this.fieldMapping.answerField} 不存在于当前模型的字段中`);
          }

          // 验证卡片内容
          const validCards = cards.filter(card => {
            return card &&
              typeof card.question === 'string' &&
              typeof card.answer === 'string' &&
              card.question.trim() !== '';
          });

          if (validCards.length === 0) {
            throw new Error('没有有效的卡片内容可导出（问题为空）');
          }

          // 对于无效卡片给出警告
          if (validCards.length < cards.length) {
            const invalidCount = cards.length - validCards.length;
            console.warn(`${invalidCount} 张卡片内容无效，将被跳过`);
          }

          // 构建Anki笔记数据，严格按照用户选择的字段映射
          const ankiNotes = validCards.map(card => {
            const fields = {};
            // 清空fields对象，确保只包含用户映射的字段
            // 严格按照用户选择的字段映射构建JSON
            fields[this.fieldMapping.questionField] = card.question.trim();
            fields[this.fieldMapping.answerField] = card.answer.trim();

            // 确保没有硬编码的'正面'和'背面'字段，只使用用户映射的字段
            return {
              deckName: this.ankiConfig.deckName,
              modelName: this.ankiConfig.modelName,
              fields: fields,
              tags: ['ankiAnalyze']
            };
          });

          console.log('准备导出的Anki笔记数据:', ankiNotes);

          // 使用用户配置的地址和端口
          const ankiConnectUrl = `http://${this.ankiConfig.server}:${this.ankiConfig.port}`;

          // 构建请求体
          const requestBody = {
            action: 'addNotes',
            version: 6,
            params: {
              notes: ankiNotes
            }
          };

          // 如果配置了API密钥，添加到请求体
          if (this.ankiConfig.apiKey) {
            requestBody.key = this.ankiConfig.apiKey;
          }

          // 发送HTTP POST请求到Anki Connect
          fetch(ankiConnectUrl, {
            method: 'POST',
            headers: {
              'Content-Type': 'application/json'
            },
            body: JSON.stringify(requestBody)
          })
            .then(response => {
              if (!response.ok) {
                throw new Error(`HTTP错误! 状态码: ${response.status}`);
              }
              return response.json();
            })
            .then(data => {
              if (data.error) {
                // 更详细地处理Anki Connect错误
                if (data.error.includes('cannot create note because it is empty')) {
                  throw new Error(`Anki Connect错误: 无法创建笔记（内容为空）。请检查卡片内容是否为空或模型字段名称是否匹配`);
                }
                // 新增：处理重复卡片错误
                if (data.error.includes('cannot create note because it is a duplicate')) {
                  throw new Error(`Anki Connect错误: 无法创建笔记（卡片重复）。这些卡片在Anki中已存在，请尝试修改内容或选择不同的卡片`);
                }
                throw new Error(`Anki Connect错误: ${data.error}`);
              }

              // 检查有多少卡片被成功添加
              const addedNotes = data.result.filter(id => id !== null).length;
              const failedNotes = data.result.length - addedNotes;

              if (failedNotes > 0) {
                // 改进警告信息，提供更具体的失败原因
                console.warn(`${failedNotes} 张卡片添加失败（可能是重复卡片或字段不匹配）`);
                // 在结果中找出失败的卡片索引
                const failedIndices = data.result
                  .map((id, index) => id === null ? index : -1)
                  .filter(index => index !== -1);

                if (failedIndices.length > 0) {
                  console.log('失败的卡片索引:', failedIndices);
                  // 可以在这里添加更详细的错误分析
                }
              }

              console.log(`成功添加 ${addedNotes} 张卡片到Anki`);
              resolve(data.result);
            })
            .catch(error => {
              console.error('发送到Anki Connect失败:', error);
              reject(error); // 直接传递原始错误，避免嵌套错误信息
            });
        } catch (error) {
          // 捕获同步错误
          console.error('导出错误:', error);
          reject(error);
        }
      });
    },

    sendToAnkiConnect(notes) {
      // 使用用户配置的地址和端口
      const ankiConnectUrl = `http://${this.ankiConfig.server}:${this.ankiConfig.port}`;

      // 构建请求体 - Anki Connect使用JSON-RPC格式
      const requestBody = {
        action: 'addNotes',
        version: 6,
        params: {
          notes: notes
        }
      };

      // 如果配置了API密钥，添加到请求体
      if (this.ankiConfig.apiKey) {
        requestBody.key = this.ankiConfig.apiKey;
      }

      // 发送HTTP POST请求到Anki Connect
      return fetch(ankiConnectUrl, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json'
        },
        body: JSON.stringify(requestBody)
      })
        .then(response => {
          if (!response.ok) {
            throw new Error(`HTTP错误! 状态码: ${response.status}`);
          }
          return response.json();
        })
        .then(data => {
          if (data.error) {
            throw new Error(`Anki Connect错误: ${data.error}`);
          }

          // 检查有多少卡片被成功添加（null表示添加失败）
          const addedNotes = data.result.filter(id => id !== null).length;
          const failedNotes = data.result.length - addedNotes;

          if (failedNotes > 0) {
            console.warn(`${failedNotes} 张卡片添加失败（可能是重复卡片）`);
          }

          console.log(`成功添加 ${addedNotes} 张卡片到Anki`);
          return data.result;
        })
        .catch(error => {
          console.error('发送到Anki Connect失败:', error);
          throw new Error(`无法连接到Anki Connect: ${error.message}\n请确保Anki已打开且已安装Anki Connect插件`);
        });
    },

    // 更新导出方法以支持异步操作
    exportSingleCard(index) {
      const card = this.cards[index];
      try {
        this.exportToAnki([card]).then(() => {
          this.showStatus(`卡片 #${index + 1} 已导出到Anki`, 'success');
        }).catch(error => {
          this.showStatus('导出失败：' + error.message, 'error');
          console.error('导出错误:', error);
        });
      } catch (error) {
        this.showStatus('导出失败：' + error.message, 'error');
        console.error('导出错误:', error);
      }
    },

    exportAllToAnki() {
      if (this.cards.length === 0) {
        this.showStatus('没有卡片可导出', 'error');
        return;
      }

      try {
        this.exportToAnki(this.cards).then(result => {
          const addedNotes = result.filter(id => id !== null).length;
          const failedNotes = result.length - addedNotes;

          if (failedNotes > 0) {
            // 显示更详细的成功/失败信息
            this.showStatus(`成功导出 ${addedNotes} 张卡片到Anki，${failedNotes} 张卡片添加失败（可能是重复卡片）`, 'info');
          } else {
            this.showStatus(`成功导出 ${addedNotes} 张卡片到Anki`, 'success');
          }
        }).catch(error => {
          // 特殊处理重复卡片错误
          if (error.message.includes('卡片重复')) {
            // 提供选项让用户选择是否继续（忽略重复卡片）
            if (confirm('部分卡片可能重复。是否继续导出非重复卡片？')) {
              // 这里可以添加去重逻辑，或者修改Anki Connect请求参数
              // 暂时我们可以简单地尝试再次导出，但需要注意这不会真正解决重复问题
              this.handleDuplicateCards();
            }
          } else {
            this.showStatus('批量导出失败：' + error.message, 'error');
          }
          console.error('批量导出错误:', error);
        });
      } catch (error) {
        this.showStatus('批量导出失败：' + error.message, 'error');
        console.error('批量导出错误:', error);
      }
    },

    // 新增：处理重复卡片的方法
    handleDuplicateCards() {
      // 这里可以实现更复杂的去重逻辑
      // 暂时我们可以选择只导出第一张卡片，跳过其余可能重复的卡片
      // 注意：这只是一个简单的示例，实际去重可能需要更复杂的逻辑

      // 创建一个临时集合用于去重
      const uniqueCards = [];
      const seenQuestions = new Set();

      for (const card of this.cards) {
        const question = card.question.trim();
        if (!seenQuestions.has(question)) {
          seenQuestions.add(question);
          uniqueCards.push(card);
        }
      }

      if (uniqueCards.length < this.cards.length) {
        this.showStatus(`已过滤 ${this.cards.length - uniqueCards.length} 张重复问题的卡片，准备导出 ${uniqueCards.length} 张唯一卡片`, 'info');
      }

      // 导出去重后的卡片
      this.exportToAnki(uniqueCards).then(result => {
        const addedNotes = result.filter(id => id !== null).length;
        this.showStatus(`成功导出 ${addedNotes} 张卡片到Anki`, 'success');
      }).catch(error => {
        this.showStatus('导出失败：' + error.message, 'error');
        console.error('导出错误:', error);
      });
    }
    ,
    // sendToAnkiConnect(notes) {
    //   const csvContent = notes.map(note => {
    //     const front = note.fields.Front.replace(/"/g, '""').replace(/\n/g, '\\n');
    //     const back = note.fields.Back.replace(/"/g, '""').replace(/\n/g, '\\n');
    //     return `"${front}","${back}"`;
    //   }).join('\n');
    //
    //   const textArea = document.createElement('textarea');
    //   textArea.value = csvContent;
    //   document.body.appendChild(textArea);
    //   textArea.select();
    //   document.execCommand('copy');
    //   document.body.removeChild(textArea);
    //
    //   console.log('CSV内容已复制到剪贴板，请在Anki中使用导入功能导入。');
    //   return true;
    // },

    generateCsv() {
      if (this.cards.length === 0) {
        this.showStatus('没有卡片可导出', 'error');
        return;
      }

      try {
        // 使用动态字段映射生成CSV标题
        const headers = [this.fieldMapping.questionField || '问题', this.fieldMapping.answerField || '答案'];
        const headerLine = headers.map(h => `"${h.replace(/"/g, '""')}"`).join(',');

        const csvContent = [
          headerLine, // 添加标题行
          ...this.cards.map(card => {
            const question = card.question.replace(/"/g, '""').replace(/\n/g, '\\n');
            const answer = card.answer.replace(/"/g, '""').replace(/\n/g, '\\n');
            return `"${question}","${answer}"`;
          })
        ].join('\n');

        const blob = new Blob([csvContent], { type: 'text/csv;charset=utf-8;' });
        const link = document.createElement('a');
        const url = URL.createObjectURL(blob);
        link.setAttribute('href', url);
        link.setAttribute('download', `anki-cards-${new Date().toISOString().split('T')[0]}.csv`);
        link.style.visibility = 'hidden';
        document.body.appendChild(link);
        link.click();
        document.body.removeChild(link);

        this.showStatus(`CSV文件已下载，包含 ${this.cards.length} 张卡片`, 'success');
      } catch (error) {
        this.showStatus('生成CSV失败：' + error.message, 'error');
        console.error('CSV生成错误:', error);
      }
    },

    showStatus(message, type = 'info') {
      this.statusMessage = message;
      this.statusType = type;

      setTimeout(() => {
        this.statusMessage = '';
      }, 3000);
    }
  }
}
</script>




<style scoped>
.app-container {
  max-width: 1200px;
  margin: 0 auto;
  padding: 20px;
  font-family: Arial, sans-serif;
}

h1 {
  color: #2c3e50;
  text-align: center;
  margin-bottom: 30px;
}

h2 {
  color: #34495e;
  margin-top: 20px;
  margin-bottom: 15px;
  font-size: 1.5em;
}

.input-section {
  background-color: #f8f9fa;
  padding: 20px;
  border-radius: 8px;
  margin-bottom: 30px;
}

textarea {
  width: 100%;
  padding: 10px;
  border: 1px solid #ddd;
  border-radius: 4px;
  font-size: 14px;
  font-family: inherit;
  resize: vertical;
  box-sizing: border-box;
}

.parse-options {
  margin-top: 15px;
  display: flex;
  align-items: center;
  gap: 15px;
  flex-wrap: wrap;
}

.format-hint {
  color: #666;
  font-size: 13px;
  margin: 0;
}

button {
  padding: 8px 16px;
  border: none;
  border-radius: 4px;
  cursor: pointer;
  font-size: 14px;
  transition: background-color 0.3s;
}

.primary-button {
  background-color: #4CAF50;
  color: white;
}

.primary-button:hover {
  background-color: #45a049;
}

.secondary-button {
  background-color: #2196F3;
  color: white;
}

.secondary-button:hover {
  background-color: #0b7dda;
}

.danger-button {
  background-color: #f44336;
  color: white;
}

.danger-button:hover {
  background-color: #da190b;
}

.cards-section {
  margin-top: 30px;
}

.cards-controls {
  display: flex;
  gap: 10px;
  margin-bottom: 20px;
  flex-wrap: wrap;
}

.cards-list {
  display: grid;
  grid-template-columns: 1fr;
  gap: 20px;
}

@media (min-width: 768px) {
  .cards-list {
    grid-template-columns: repeat(2, 1fr);
  }
}

.card-item {
  background-color: #ffffff;
  border: 1px solid #e0e0e0;
  border-radius: 8px;
  padding: 20px;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}

.card-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 15px;
  padding-bottom: 10px;
  border-bottom: 1px solid #eee;
}

.card-index {
  font-weight: bold;
  color: #666;
}

.card-actions {
  display: flex;
  gap: 5px;
}

.edit-button { background-color: #2196F3; color: white; }
.delete-button { background-color: #f44336; color: white; }
.export-button { background-color: #4CAF50; color: white; }
.save-button { background-color: #4CAF50; color: white; }
.cancel-button { background-color: #9e9e9e; color: white; }

.card-content .card-question,
.card-content .card-answer {
  margin-bottom: 10px;
}

.card-content p {
  margin: 5px 0 0 0;
  white-space: pre-wrap;
}

.card-edit-form .form-group {
  margin-bottom: 15px;
}

.card-edit-form label {
  display: block;
  margin-bottom: 5px;
  font-weight: bold;
}

.card-edit-form textarea {
  width: 100%;
  min-height: 60px;
}

.edit-actions {
  display: flex;
  gap: 10px;
  justify-content: flex-end;
  margin-top: 15px;
}

.status-message {
  position: fixed;
  bottom: 20px;
  left: 50%;
  transform: translateX(-50%);
  padding: 12px 20px;
  border-radius: 4px;
  color: white;
  font-weight: bold;
  z-index: 1000;
  box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
}


/* 添加配置区域样式 */

.form-group {
  flex: 1;
  min-width: 200px;
}

.form-group label {
  display: block;
  margin-bottom: 5px;
  font-weight: bold;
  color: #495057;
}

.form-group input {
  width: 100%;
  padding: 8px 12px;
  border: 1px solid #ced4da;
  border-radius: 4px;
  font-size: 14px;
  box-sizing: border-box;
}

.form-group input:focus {
  outline: none;
  border-color: #4CAF50;
  box-shadow: 0 0 0 2px rgba(76, 175, 80, 0.2);
}

/* 响应式设计 */
@media (max-width: 768px) {
  .form-row {
    flex-direction: column;
  }

  .form-group {
    min-width: 100%;
  }
}

/* 添加配置按钮样式 */
.header-actions {
  margin-bottom: 20px;
  text-align: left;
}

.config-button {
  background-color: #2196F3;
  color: white;
  padding: 10px 20px;
  border: none;
  border-radius: 4px;
  cursor: pointer;
  font-size: 14px;
  font-weight: bold;
}

.config-button:hover {
  background-color: #0b7dda;
}
.mapping-info {
  color: #1565c0;
  font-size: 14px;
  margin-top: 10px;
  padding: 10px;
  background-color: #e3f2fd;
  border-radius: 4px;
  border-left: 4px solid #1976d2;
}

.card-question strong,
.card-answer strong {
  color: #333;
  display: block;
  margin-bottom: 5px;
  font-size: 14px;
}
.field-mapping-section {
  background-color: #f8f9fa;
  padding: 20px;
  border-radius: 8px;
  margin-bottom: 20px;
  border: 1px solid #e9ecef;
}

.field-mapping-controls {
  display: flex;
  flex-wrap: wrap;
  gap: 20px;
  align-items: end;
  margin-bottom: 15px;
}

.field-mapping-item {
  flex: 1;
  min-width: 200px;
}

.field-mapping-item label {
  display: block;
  margin-bottom: 8px;
  font-weight: 600;
  color: #495057;
}

.field-select {
  width: 100%;
  padding: 10px 12px;
  border: 1px solid #ced4da;
  border-radius: 4px;
  font-size: 14px;
  background-color: white;
  cursor: pointer;
  box-sizing: border-box;
  transition: border-color 0.2s, box-shadow 0.2s;
}

.field-select:focus {
  outline: none;
  border-color: #2196F3;
  box-shadow: 0 0 0 3px rgba(33, 150, 243, 0.2);
}

.apply-mapping-button {
  align-self: flex-end;
  height: fit-content;
  padding: 10px 16px;
}

@media (max-width: 768px) {
  .field-mapping-controls {
    flex-direction: column;
    align-items: stretch;
  }

  .field-mapping-item {
    min-width: 100%;
  }

  .apply-mapping-button {
    align-self: stretch;
  }
}

</style>
